package someTestExcemple.huaweiOd.container.array;
import java.util.*;
import java.util.stream.Collectors;
//https://blog.csdn.net/guorui_java/article/details/146971416

//华为OD机试 - 水果摊小买卖（Java 2025 A卷 200分）

/**
 * 一、题目描述
 * 小王手里有点闲钱，想着做点卖水果的小买卖。
 * 给出两个数组m, n，用 m[i] 代表第 i 个水果的成本价，n[i] 代表第 i 个水果能卖出的价钱，假如现在有本钱 k，试问最后最多能赚多少钱？
 * 说明：
 * 每种水果只需买一次，只能卖一次。
 * 数组 m、n 大小不超过 50。
 * 数组元素为正整数，不超过 1000。
 * 二、输入描述
 * 数组 m、n
 * 本钱 k
 * 备注：
 * 第一行输入逗号分隔的数组 m 的元素值
 * 第二行输入逗号分隔的数组 n 的元素值
 * 第三行输入本钱
 * 三、输出描述
 * 最多能赚取多少钱。
 * 测试用例1
 * 输入
 * 3,4,5
 * 3,3,5
 * 10
 *
 * 输出
 * 10
 * 说明:三个水果中利润均不大于0（利润分别为0, -1, 0），因此不进行交易，最终资金仍为10
 */
//思路：
/**
 * 根据输入构造每个水果的成本和利润（卖出价减去成本），仅保留利润大于0的水果。
 * 按照水果成本从小到大排序，便于在资金不断增长时逐步加入可购买的水果。
 * 贪心+优先队列：
 * 维护一个最大堆（优先队列），将所有当前资金能购买的水果放入堆中，堆中以利润降序排列。
 * 每次从堆中取出利润最大的水果进行交易，更新资金；并将因资金增加而变得可购买的水果加入堆中。
 * 重复该过程，直至没有可购买的水果。
 * 最终资金即为最大能赚到的钱。
 */
public class GreenGrocer {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int[] costPriceList = Arrays.stream(sc.nextLine().split(",")).
                mapToInt(Integer::parseInt).toArray();
        int[] salesPriceList = Arrays.stream(sc.nextLine().split(",")).
                mapToInt(Integer::parseInt).toArray();
        int money = Integer.parseInt(sc.nextLine());
        //详细逻辑
        //设置可以获利的水果
        List<Fruit>  profitList = new ArrayList<>();
        for(int i=0;i<salesPriceList.length;i++) {
            if(salesPriceList[i] - costPriceList[i] > 0) {
                Fruit fruit = new Fruit(costPriceList[i], salesPriceList[i],i); //构造函数里面算好了利润
                profitList.add(fruit);
            }
        }
        //获利水果按成本升序 --由于Map是无序的，所以写到这里想到能用Map，而应该自己定义一个获利水果类
        //或者外面再包一层List
        //todo Stream流各种写法要熟悉
        profitList = profitList.stream().
                sorted(Comparator.comparing(a -> a.costPrice)).collect(Collectors.toList());
        //没有利润大于0的水果，或者最便宜的水果都买不起,直接返回初始资金
        if(profitList.isEmpty() || money < profitList.get(0).costPrice){
            System.out.println(money);
            return;
        }
        //设一个优先队列，放当前的钱可以买到的获利水果--按利润降序排序
        //这个队列是随着资金不断增长而变化的
        PriorityQueue<Fruit> fruitQueue = new PriorityQueue<>((a,b)->b.profit - a.profit);
        int index =0; //当前可以买的获利水果的最大成本水果下标
        while(true) {
            //拿出最大利润的水果
            //将当前的资金可以买的水果入优先队列
            while(index < profitList.size() && money >= profitList.get(index).costPrice) {
                //将当前可以买的水果加入优先队列
                fruitQueue.offer(profitList.get(index)); //与 add 方法的区别在于，offer 在队列容量有限时不会抛出异常，
                // 而是返回 false（不过 PriorityQueue 本身没有容量限制，除非显式使用有界队列包装）
                index++;
            }
            //while循环后index的位置就是当前资金能买的成本最高水果的下一个位置
            if(fruitQueue.isEmpty()) {
                break;
            }
            //取队头元素-也就是利润最大的元素
            Fruit fruit = fruitQueue.poll();
            // 而是返回 false（不过 PriorityQueue 本身没有容量限制，除非显式使用有界队列包装）。
            money += fruit.profit;

        }
        System.out.println(money);
    }

    public static class Fruit{
        int index;
        int costPrice;
        int salesPrice;
        int profit;
        public Fruit(int costPrice, int salesPrice,int index) {
            this.costPrice = costPrice;
            this.salesPrice = salesPrice;
            this.profit = salesPrice - costPrice;
            this.index = index;
        }
        public String toString() {
            return "Fruit{" +
                    "index=" + index +
                    ", costPrice=" + costPrice +
                    ", salesPrice=" + salesPrice +
                    ", profit=" + profit +
                    '}';
        }
    }
}
